﻿// $Id: ValidationDelegationRule.cs 10 2008-02-29 15:58:02Z mcartoixa $

/* ***************************************************************************
 *                                                                           *
 * Copyright © 2007 NourY Solutions                                          *
 *                                                                           *
 * This file is part of DataRules.                                           *
 *                                                                           *
 * DataRules is free software; you can redistribute it and/or modify it      *
 * under the terms of the GNU Lesser General Public License as published     *
 * by the Free Software Foundation; either version 3 of the License, or      *
 * (at your option) any later version.                                       *
 *                                                                           *
 * DataRules is distributed in the hope that it will be useful, but          *
 * WITHOUT ANY WARRANTY; without even the implied warranty of                *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU          *
 * Lesser General Public License for more details.                           *
 *                                                                           *
 * You should have received a copy of the GNU Lesser General Public          *
 * License along with this program.  If not, see                             *
 * <http://www.gnu.org/licenses/lgpl.html>.                                  *
 *                                                                           *
 *************************************************************************** */

/*! \file
 * \brief Definition of \c Salamanca.DataRules.ValidationDelegationRule.
 *
 * \author $Author: mcartoixa $
 * \date $Date: 2008-02-29 16:58:02 +0100 (ven., 29 févr. 2008) $
 * \version $Revision: 10 $
 */

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

namespace Salamanca.DataRules
{



    ///////////////////////////////////////////////////////////////////////////
    ///
    /// <summary>Business rule that is delegated to another <see cref="IValidatable" /> instance.</summary>
    ///
    ///////////////////////////////////////////////////////////////////////////

    public class ValidationDelegationRule<T>:
        Rule
    {

        /// <summary>Constructor.</summary>
        /// <param name="description">The description of the rule.</param>
        /// <param name="delegatee">The <see cref="IValidatable" /> instance which the validation is delegated to.</param>
        /// <param name="delegateePropertyName">The name of the <paramref name="delegatee" /> property that must be validated. For a general validation, this can be the empty string (<c>""</c>).</param>
        /// <exception cref="ArgumentNullException">
        ///   <para><paramref name="description" /> is <c>null</c>.</para>
        ///   <para><paramref name="delegatee" /> is <c>null</c>.</para>
        ///   <para><paramref name="delegateePropertyName" /> is <c>null</c>.</para>
        /// </exception>
        public ValidationDelegationRule(string description, IValidatable delegatee, string delegateePropertyName):
            this(string.Empty, description, delegatee, delegateePropertyName)
        {
        }

        /// <summary>Constructor.</summary>
        /// <param name="propertyName">The name of the property which the rule applies to. For a general rule, this can be the empty string (<c>""</c>).</param>
        /// <param name="description">The description of the rule.</param>
        /// <param name="delegatee">The <see cref="IValidatable" /> instance which the validation is delegated to.</param>
        /// <param name="delegateePropertyName">The name of the <paramref name="delegatee" /> property that must be validated. For a general validation, this can be the empty string (<c>""</c>).</param>
        /// <exception cref="ArgumentNullException">
        ///   <para><paramref name="propertyName" /> is <c>null</c>.</para>
        ///   <para><paramref name="description" /> is <c>null</c>.</para>
        ///   <para><paramref name="delegatee" /> is <c>null</c>.</para>
        ///   <para><paramref name="delegateePropertyName" /> is <c>null</c>.</para>
        /// </exception>
        public ValidationDelegationRule(string propertyName, string description, IValidatable delegatee, string delegateePropertyName):
            base(propertyName, description)
        {
            Debug.Assert(delegatee!=null);
            if (delegatee==null)
                throw new ArgumentNullException("delegatee");
            Debug.Assert(delegateePropertyName!=null);
            if (delegateePropertyName==null)
                throw new ArgumentNullException("delegateePropertyName");

            _Delegatee=delegatee;
            _DelegateePropertyName=delegateePropertyName;
        }

        /// <summary>Validates the rule on the specified target.</summary>
        /// <param name="target">The instance against which the rule is validated.</param>
        /// <returns><c>true</c> if the instance is valid for the rule, <c>false</c> if not.</returns>
        protected override bool DoValidate(object target)
        {
            IList<IRule> br=_Delegatee.GetBrokenRules(_DelegateePropertyName);

            StringBuilder d=new StringBuilder(Rules.GetMessage(br));
            d.Replace(
#if (!NET_CF)
                Environment.NewLine,
                Environment.NewLine+"\t"
#else
                "\r\n",
                "\r\n\t"
#endif
            );
            _Description=d.ToString().Trim();

            return (br.Count==0);
        }

        /// <summary>The description of the rule.</summary>
        public override string Description
        {
            get
            {
                if (string.IsNullOrEmpty(_Description))
                    return base.Description;

                StringBuilder d=new StringBuilder(_Description);
                d.Insert(
                    0,
#if (!NET_CF)
                    Environment.NewLine+"\t"
#else
                    "\r\n\t"
#endif
                );
                d.Insert(0, base.Description);

                return d.ToString().Trim();
            }
        }

        private IValidatable _Delegatee;
        private string _DelegateePropertyName;
        private string _Description;
    }
}
